

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <title>BlockBuilder - LiterateCS</title>

	<link rel="icon" type="image/x-icon" href="../images/favicon.ico">
    <link rel="stylesheet" href="../bootstrap/css/readable/bootstrap.min.css" />
<link rel="stylesheet" href="../font-awesome/css/font-awesome.min.css">
<link rel="stylesheet" href="../sidebar/sidebar.min.css" />
<link rel="stylesheet" href="../css/book.min.css" />
<link rel="stylesheet" href="../syntax-highlight/solarized-light.min.css" />
<link rel="stylesheet" href="../mermaid/mermaid.css" />

</head>

<body>
    
    <nav class="navbar navbar-inverse navbar-fixed-top">
        <div class="container">
            <div class="navbar-header">
                <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
                    <span class="sr-only">Toggle navigation</span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                </button>
                <a class="navbar-brand" href="#sidebar-toggle" id="sidebar-toggle">
					<span>
						<img src="../images/favicon.ico" height="24" class="hidden-sm hidden-xs" />
						<i id="sidebar-toggle-icon" class="hidden-md hidden-lg hidden-xl fa fa-angle-double-right" aria-hidden="true"></i>
						LiterateCS
					</span>
				</a>
            </div>
            <div id="navbar" class="navbar-collapse collapse">
                <ul class="nav navbar-nav">
                    <li><a href="../index.html"><i class="fa fa-home" aria-hidden="true"></i> Home</a></li>
					<li><a href="https://github.com/johtela/LiterateCS"><i class="fa fa-github" aria-hidden="true"></i> GitHub Repository</a></li>
                    <li><a href="https://www.nuget.org/packages/LiterateCS/"><i class="fa fa-download" aria-hidden="true"></i> Download</a></li>
                    <li><a href="../License.html">License</a></li>
                </ul>
            </div>
        </div>
    </nav>

    <div class="container">
        <div class="row">
            <div id="sidebar" class="col-md-3 hidden-sm hidden-xs">
                
        <div class="panel panel-default">
            <div class="panel-heading">
                <h4>On This Page</h4>
            </div>
            <div id="header-menu" class="panel-body main-menu">
                <ul></ul>
            </div>
        </div>  
        <div class="panel panel-default">
            <div class="panel-heading">
                <h4>Table of Contents</h4>
            </div>
            <div class="panel-body main-menu">
                <ul>
	<li><a href="../index.html">Home</a></li>
	<ul>
	</ul>
	<li><a href="../Introduction.html">Introduction</a></li>
	<ul>
	</ul>
	<li><a href="../LiterateCS/Options.html">Command Line Options</a></li>
	<ul>
	</ul>
	<li><a href="../LiterateCS/Program.html">Main Program</a></li>
	<ul>
	</ul>
	<li><a href="../LiterateCS/SplitPath.html">SplitPath Structure</a></li>
	<ul>
	</ul>
	<li><a href="../LiterateCS/Weaver.html">Document Weaver</a></li>
	<ul>
	</ul>
	<li><a href="../LiterateCS/MdWeaver.html">Markdown Weaver</a></li>
	<ul>
	</ul>
	<li><a href="../LiterateCS/HtmlWeaver.html">HTML Weaver</a></li>
	<ul>
	</ul>
	<li><a href="../LiterateCS/TocManager.html">TOC Manager</a></li>
	<ul>
	</ul>
	<li><a href="../LiterateCS/BlockList.html">Source Blocks</a></li>
	<ul>
	</ul>
	<li><a href="../LiterateCS/Macro.html">Macros</a></li>
	<ul>
	</ul>
	<li><a href="../LiterateCS/BlockBuilder.html" class="selected">Block Builder</a></li>
	<ul>
	</ul>
	<li><a href="../LiterateCS/HtmlBlockBuilder.html">HTML Block Builder</a></li>
	<ul>
	</ul>
	<li><a href="../LiterateCS/HtmlGenerator.html">HTML Generation</a></li>
	<ul>
	</ul>
	<li>Themes</li>
	<ul>
<ul>
	<li><a href="../LiterateCS.Theme/DirHelpers.html">Directory Utilities</a></li>
	<ul>
	</ul>
	<li><a href="../LiterateCS.Theme/Toc.html">Table of Contents Classes</a></li>
	<ul>
	</ul>
	<li><a href="../LiterateCS.Theme/PageParams.html">Page Parameters</a></li>
	<ul>
	</ul>
	<li><a href="../LiterateCS.Theme/Theme.html">Theme Base Class</a></li>
	<ul>
	</ul>
	<li><a href="../LiterateCS.Theme/LiterateException.html">Reporting Errors</a></li>
	<ul>
	</ul>
</ul>
	</ul>
	<li><a href="../FrontMatter.html">Front Matter</a></li>
	<ul>
	</ul>
	<li><a href="../TableOfContents.html">Table of Contents File</a></li>
	<ul>
	</ul>
	<li><a href="../TipsAndTricks.html">Tips &amp; Tricks</a></li>
	<ul>
	</ul>
	<li><a href="../License.html">License</a></li>
	<ul>
	</ul>
	<li><a href="../README.html">README</a></li>
	<ul>
	</ul>
	<li><a href="../Installation.html">Installation</a></li>
	<ul>
	</ul>
</ul>
            </div>
        </div>

            </div>
			<div id="contentarea" class="col-md-9 col-sm-12 col-sm-push-0 col-xs-12 col-xs-push-0">
				<ul class="pager">
	<li class="previous"><a href="../LiterateCS/Macro.html">Previous: Macros</a></li>
	<li class="next"><a href="../LiterateCS/HtmlBlockBuilder.html">Next: HTML Block Builder</a></li>
</ul>
				<div id="static-content" class="markdown">
					<h1 id="splitting-files-into-blocks">Splitting Files into Blocks</h1>
<p>The task of the block builder is to extract a block list from a source file.
We use a simple regular expression to split markdown files into blocks, but with
C# files we utilize a more sophisticated tool: the <a href="https://github.com/dotnet/roslyn">Roslyn</a>
compiler platform. Roslyn comprises a set of libraries and APIs that expose all
facets of the C# compiler: lexer, parser, type checker, code generator, and so on.
This is the same compiler that is used by Visual Studio and other official Microsoft
tools, so it should be always complete and up-to-date.</p>
<p>We need only the parser to separate documentation and code, but we can take
advantage of other parts of Roslyn too. For example, we can use the semantic analysis
to distinguish which identifiers represent types and highlight them in the output
as Visual Studio does. We can also get the type information of any expression
and show it in a tooltip window.</p>
<p>The semantic information is useful only in conjunction with HTML output, though.
In markdown we cannot make use of it, mostly because the code blocks cannot be
augmented with styling information. Even if there was a way to add metadata to
code blocks, any of the markdown-to-HTML converters would not probably use it.
Consequently, we defer utilizing the semantic information to the
<a href="HtmlBlockBuild.html">HtmlBlockBuilder</a> class which is used in context of HTML
output.</p>
<p>So, let's tackle the parsing problem first, and see how it is performed by
the BlockBuilder class.</p>
<pre class="csharp"><code class="csharp"><span class="keyword" id="LiterateCS">namespace</span> LiterateCS
<span class="punctuation">{</span>
	<span class="keyword">using</span> Microsoft<span class="punctuation">.</span>CodeAnalysis<span class="punctuation">;</span>
	<span class="keyword">using</span> Microsoft<span class="punctuation">.</span>CodeAnalysis<span class="punctuation">.</span>CSharp<span class="punctuation">;</span>
	<span class="keyword">using</span> Microsoft<span class="punctuation">.</span>CodeAnalysis<span class="punctuation">.</span>CSharp<span class="punctuation">.</span>Syntax<span class="punctuation">;</span>
	<span class="keyword">using</span> System<span class="punctuation">.</span>Collections<span class="punctuation">.</span>Generic<span class="punctuation">;</span>
	<span class="keyword">using</span> System<span class="punctuation">.</span>IO<span class="punctuation">;</span>
	<span class="keyword">using</span> System<span class="punctuation">.</span>Linq<span class="punctuation">;</span>
	<span class="keyword">using</span> System<span class="punctuation">.</span>Text<span class="punctuation">.</span>RegularExpressions<span class="punctuation">;</span>
	<span class="keyword">using</span> ExtensionCord<span class="punctuation">;</span>
</code></pre>
<h2 id="syntax-walker">Syntax Walker</h2>
<p>BlockBuilder inherits from <a href="http://www.coderesx.com/roslyn/html/B6833F66.htm">CSharpSyntaxWalker</a>,
which implements the <a href="https://en.wikipedia.org/wiki/Visitor_pattern">visitor pattern</a>.
It &quot;walks&quot; through an abstract syntax tree and calls a particular
virtual method in the class based on the type of the node visited.
Inheriting from the walker allows us to visit only specific types of
syntactic elements and ignore the ones we are not interested in.</p>
<pre class="csharp"><code class="csharp">	<span class="keyword" id="LiterateCS.BlockBuilder">public</span> <span class="keyword">class</span> <span class="typename">BlockBuilder</span> <span class="punctuation">:</span> <span class="typename" data-toggle="tooltip" title="Microsoft.CodeAnalysis.CSharp.CSharpSyntaxWalker">CSharpSyntaxWalker</span>
	<span class="punctuation">{</span>
</code></pre>
<p>We are extracting multi-line comment blocks, that is, comments
starting with <code>/*</code>. To get the contents of a comment block, we need
to strip the comment delimiters using a regular expression. The
following regex matches a comment body.</p>
<pre class="csharp"><code class="csharp">		<span class="keyword">private</span> <span class="keyword">static</span> <span class="typename" data-toggle="tooltip" title="System.Text.RegularExpressions.Regex">Regex</span> <span id="LiterateCS.BlockBuilder._commentBody">_commentBody</span> <span class="punctuation">=</span> <span class="keyword" data-toggle="tooltip" title="System.Text.RegularExpressions.Regex">new</span> <span class="typename">Regex</span> <span class="punctuation">(</span><span class="string" data-toggle="tooltip" title="string">@&quot;/\*(.*?)\*/&quot;</span><span class="punctuation">,</span>
			<span class="typename" data-toggle="tooltip" title="System.Text.RegularExpressions.RegexOptions">RegexOptions</span><span class="punctuation" data-toggle="tooltip" title="System.Text.RegularExpressions.RegexOptions">.</span><span data-toggle="tooltip" title="System.Text.RegularExpressions.RegexOptions">Singleline</span> <span class="punctuation" data-toggle="tooltip" title="System.Text.RegularExpressions.RegexOptions">|</span> <span class="typename" data-toggle="tooltip" title="System.Text.RegularExpressions.RegexOptions">RegexOptions</span><span class="punctuation" data-toggle="tooltip" title="System.Text.RegularExpressions.RegexOptions">.</span><span data-toggle="tooltip" title="System.Text.RegularExpressions.RegexOptions">Compiled</span><span class="punctuation">)</span><span class="punctuation">;</span>
</code></pre>
<p>The following regex matches a macro expansion line. A macro expansion
line begins with <code>&lt;&lt;</code> and ends with <code>&gt;&gt;</code>. Whitespace before and after
the double angle brackets is ignored.</p>
<pre class="csharp"><code class="csharp">		<span class="keyword">private</span> <span class="keyword">static</span> <span class="typename" data-toggle="tooltip" title="System.Text.RegularExpressions.Regex">Regex</span> <span id="LiterateCS.BlockBuilder._macroLine">_macroLine</span> <span class="punctuation">=</span> <span class="keyword" data-toggle="tooltip" title="System.Text.RegularExpressions.Regex">new</span> <span class="typename">Regex</span> <span class="punctuation">(</span><span class="string" data-toggle="tooltip" title="string">@&quot;^\s*(&lt;&lt;.*&gt;&gt;)\s*$&quot;</span><span class="punctuation">,</span>
			<span class="typename" data-toggle="tooltip" title="System.Text.RegularExpressions.RegexOptions">RegexOptions</span><span class="punctuation" data-toggle="tooltip" title="System.Text.RegularExpressions.RegexOptions">.</span><span data-toggle="tooltip" title="System.Text.RegularExpressions.RegexOptions">Multiline</span> <span class="punctuation" data-toggle="tooltip" title="System.Text.RegularExpressions.RegexOptions">|</span> <span class="typename" data-toggle="tooltip" title="System.Text.RegularExpressions.RegexOptions">RegexOptions</span><span class="punctuation" data-toggle="tooltip" title="System.Text.RegularExpressions.RegexOptions">.</span><span data-toggle="tooltip" title="System.Text.RegularExpressions.RegexOptions">Compiled</span><span class="punctuation">)</span><span class="punctuation">;</span>
</code></pre>
<p>While building the linked list of block, we need to maintain the latest
(current) block as well as the first block (head of the list).</p>
<pre class="csharp"><code class="csharp">		<span class="keyword">private</span> <span class="typename" data-toggle="tooltip" title="LiterateCS.BlockList"><a href="../LiterateCS/BlockList.html#LiterateCS.BlockList">BlockList</a></span> <span id="LiterateCS.BlockBuilder._currentBlock">_currentBlock</span><span class="punctuation">;</span>
		<span class="keyword">private</span> <span class="typename" data-toggle="tooltip" title="LiterateCS.BlockList"><a href="../LiterateCS/BlockList.html#LiterateCS.BlockList">BlockList</a></span> <span id="LiterateCS.BlockBuilder._blocks">_blocks</span><span class="punctuation">;</span>
</code></pre>
<p>Macros require additional stored state. Since regions can be nested, we
need a stack for macros defined in a code file. The innermost region
is stored at the top of the stack.</p>
<pre class="csharp"><code class="csharp">		<span class="keyword">private</span> <span class="typename" data-toggle="tooltip" title="System.Collections.Generic.Stack<LiterateCS.Macro>">Stack</span><span class="punctuation">&lt;</span><span class="typename" data-toggle="tooltip" title="LiterateCS.Macro"><a href="../LiterateCS/Macro.html#LiterateCS.Macro">Macro</a></span><span class="punctuation">&gt;</span> <span id="LiterateCS.BlockBuilder._macros">_macros</span> <span class="punctuation">=</span> <span class="keyword" data-toggle="tooltip" title="System.Collections.Generic.Stack<LiterateCS.Macro>">new</span> <span class="typename">Stack</span><span class="punctuation">&lt;</span><span class="typename" data-toggle="tooltip" title="LiterateCS.Macro"><a href="../LiterateCS/Macro.html#LiterateCS.Macro">Macro</a></span><span class="punctuation">&gt;</span> <span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">;</span>
</code></pre>
<p>When we encounter either <code>#region</code> or <code>#endregion</code> directive, we must
start a new block. The boolean flag below triggers creating a new block.
We also need to remember what the was the first region opened after the
macro was started or ended.</p>
<pre class="csharp"><code class="csharp">		<span class="keyword">private</span> <span class="keyword" data-toggle="tooltip" title="bool">bool</span> <span id="LiterateCS.BlockBuilder._startNewBlock">_startNewBlock</span><span class="punctuation">;</span>
		<span class="keyword">private</span> <span class="typename" data-toggle="tooltip" title="LiterateCS.BlockList"><a href="../LiterateCS/BlockList.html#LiterateCS.BlockList">BlockList</a></span> <span id="LiterateCS.BlockBuilder._newBlock">_newBlock</span><span class="punctuation">;</span>
</code></pre>
<h2 id="constructor">Constructor</h2>
<p>We need the command line options to access the parameters controlling
the parsing. The Options object is given as an argument to the constructor,
as usual.</p>
<pre class="csharp"><code class="csharp">		<span class="keyword">protected</span> <span class="typename" data-toggle="tooltip" title="LiterateCS.Options"><a href="../LiterateCS/Options.html#LiterateCS.Options">Options</a></span> <span id="LiterateCS.BlockBuilder._options">_options</span><span class="punctuation">;</span>
		<span class="keyword">protected</span> <span class="keyword" data-toggle="tooltip" title="string">string</span> <span id="LiterateCS.BlockBuilder._currentFile">_currentFile</span><span class="punctuation">;</span>

		<span class="keyword" id="LiterateCS.BlockBuilder.BlockBuilder(LiterateCS.Options)" data-toggle="tooltip" title="LiterateCS.BlockBuilder.BlockBuilder(LiterateCS.Options)">public</span> <span data-toggle="tooltip" title="LiterateCS.BlockBuilder.BlockBuilder(LiterateCS.Options)">BlockBuilder</span> <span class="punctuation">(</span><span class="typename" data-toggle="tooltip" title="LiterateCS.Options"><a href="../LiterateCS/Options.html#LiterateCS.Options">Options</a></span> options<span class="punctuation">)</span>
			<span class="punctuation" data-toggle="tooltip" title="void">:</span> <span class="keyword" data-toggle="tooltip" title="void">base</span> <span class="punctuation">(</span><span class="typename" data-toggle="tooltip" title="Microsoft.CodeAnalysis.SyntaxWalkerDepth">SyntaxWalkerDepth</span><span class="punctuation" data-toggle="tooltip" title="Microsoft.CodeAnalysis.SyntaxWalkerDepth">.</span><span data-toggle="tooltip" title="Microsoft.CodeAnalysis.SyntaxWalkerDepth">StructuredTrivia</span><span class="punctuation">)</span>
		<span class="punctuation">{</span>
			<span data-toggle="tooltip" title="LiterateCS.Options"><a href="../LiterateCS/BlockBuilder.html#LiterateCS.BlockBuilder._options">_options</a></span> <span class="punctuation" data-toggle="tooltip" title="LiterateCS.Options">=</span> <span data-toggle="tooltip" title="LiterateCS.Options">options</span><span class="punctuation">;</span>
		<span class="punctuation">}</span>
</code></pre>
<h2 id="generating-block-lists-from-code-file">Generating Block Lists from Code File</h2>
<p>The methods that generate block lists from code are defined below.
There are two variants: one takes a file and the other takes a Roslyn
<a href="https://github.com/dotnet/roslyn/wiki/Roslyn-Overview#solutions-projects-documents">Document</a>.
The implementations are basically the same in both cases. They differ
only in how the AST is obtained.</p>
<pre class="csharp"><code class="csharp">		<span class="keyword" id="LiterateCS.BlockBuilder.FromCodeFile(string)" data-toggle="tooltip" title="LiterateCS.BlockBuilder.FromCodeFile(string)">public</span> <span class="keyword" data-toggle="tooltip" title="LiterateCS.BlockBuilder.FromCodeFile(string)">virtual</span> <span class="typename" data-toggle="tooltip" title="LiterateCS.BlockList"><a href="../LiterateCS/BlockList.html#LiterateCS.BlockList">BlockList</a></span> <span data-toggle="tooltip" title="LiterateCS.BlockBuilder.FromCodeFile(string)">FromCodeFile</span> <span class="punctuation">(</span><span class="keyword" data-toggle="tooltip" title="string">string</span> codeFile<span class="punctuation">)</span>
		<span class="punctuation">{</span>
			<span data-toggle="tooltip" title="string"><a href="../LiterateCS/BlockBuilder.html#LiterateCS.BlockBuilder._currentFile">_currentFile</a></span> <span class="punctuation" data-toggle="tooltip" title="string">=</span> <span data-toggle="tooltip" title="string">codeFile</span><span class="punctuation">;</span>
			<span class="keyword" data-toggle="tooltip" title="Microsoft.CodeAnalysis.SyntaxTree">var</span> <span id="tree">tree</span> <span class="punctuation">=</span> <span class="typename" data-toggle="tooltip" title="Microsoft.CodeAnalysis.CSharp.CSharpSyntaxTree">CSharpSyntaxTree</span><span class="punctuation" data-toggle="tooltip" title="Microsoft.CodeAnalysis.CSharp.CSharpSyntaxTree.ParseText(string, Microsoft.CodeAnalysis.CSharp.CSharpParseOptions, string, System.Text.Encoding, System.Threading.CancellationToken)">.</span><span data-toggle="tooltip" title="Microsoft.CodeAnalysis.CSharp.CSharpSyntaxTree.ParseText(string, Microsoft.CodeAnalysis.CSharp.CSharpParseOptions, string, System.Text.Encoding, System.Threading.CancellationToken)">ParseText</span> <span class="punctuation">(</span><span class="typename" data-toggle="tooltip" title="System.IO.File">File</span><span class="punctuation" data-toggle="tooltip" title="System.IO.File.ReadAllText(string)">.</span><span data-toggle="tooltip" title="System.IO.File.ReadAllText(string)">ReadAllText</span> <span class="punctuation">(</span><span data-toggle="tooltip" title="string">codeFile</span><span class="punctuation">)</span><span class="punctuation">)</span><span class="punctuation">;</span>
			<span class="keyword">return</span> <span data-toggle="tooltip" title="LiterateCS.BlockBuilder.CreateForTree(Microsoft.CodeAnalysis.SyntaxTree)"><a href="../LiterateCS/BlockBuilder.html#LiterateCS.BlockBuilder.CreateForTree(Microsoft.CodeAnalysis.SyntaxTree)">CreateForTree</a></span> <span class="punctuation">(</span><span data-toggle="tooltip" title="Microsoft.CodeAnalysis.SyntaxTree">tree</span><span class="punctuation">)</span><span class="punctuation">;</span>
		<span class="punctuation">}</span>

		<span class="keyword" id="LiterateCS.BlockBuilder.FromDocument(Microsoft.CodeAnalysis.Document)" data-toggle="tooltip" title="LiterateCS.BlockBuilder.FromDocument(Microsoft.CodeAnalysis.Document)">public</span> <span class="keyword" data-toggle="tooltip" title="LiterateCS.BlockBuilder.FromDocument(Microsoft.CodeAnalysis.Document)">virtual</span> <span class="typename" data-toggle="tooltip" title="LiterateCS.BlockList"><a href="../LiterateCS/BlockList.html#LiterateCS.BlockList">BlockList</a></span> <span data-toggle="tooltip" title="LiterateCS.BlockBuilder.FromDocument(Microsoft.CodeAnalysis.Document)">FromDocument</span> <span class="punctuation">(</span><span class="typename" data-toggle="tooltip" title="Microsoft.CodeAnalysis.Document">Document</span> document<span class="punctuation">)</span>
		<span class="punctuation">{</span>
			<span data-toggle="tooltip" title="string"><a href="../LiterateCS/BlockBuilder.html#LiterateCS.BlockBuilder._currentFile">_currentFile</a></span> <span class="punctuation" data-toggle="tooltip" title="string">=</span> <span data-toggle="tooltip" title="Microsoft.CodeAnalysis.Document">document</span><span class="punctuation" data-toggle="tooltip" title="string">.</span><span data-toggle="tooltip" title="string">FilePath</span><span class="punctuation">;</span>
			<span class="keyword" data-toggle="tooltip" title="Microsoft.CodeAnalysis.SyntaxTree">var</span> tree <span class="punctuation">=</span> <span data-toggle="tooltip" title="Microsoft.CodeAnalysis.Document">document</span><span class="punctuation" data-toggle="tooltip" title="Microsoft.CodeAnalysis.Document.GetSyntaxTreeAsync(System.Threading.CancellationToken)">.</span><span data-toggle="tooltip" title="Microsoft.CodeAnalysis.Document.GetSyntaxTreeAsync(System.Threading.CancellationToken)">GetSyntaxTreeAsync</span> <span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation" data-toggle="tooltip" title="Microsoft.CodeAnalysis.SyntaxTree">.</span><span data-toggle="tooltip" title="Microsoft.CodeAnalysis.SyntaxTree">Result</span><span class="punctuation">;</span>
			<span class="keyword">return</span> <span data-toggle="tooltip" title="LiterateCS.BlockBuilder.CreateForTree(Microsoft.CodeAnalysis.SyntaxTree)"><a href="../LiterateCS/BlockBuilder.html#LiterateCS.BlockBuilder.CreateForTree(Microsoft.CodeAnalysis.SyntaxTree)">CreateForTree</a></span> <span class="punctuation">(</span><span data-toggle="tooltip" title="Microsoft.CodeAnalysis.SyntaxTree">tree</span><span class="punctuation">)</span><span class="punctuation">;</span>
		<span class="punctuation">}</span>
</code></pre>
<h2 id="generating-block-list-from-markdown-file">Generating Block List from Markdown File</h2>
<p>Parsing a markdown file is simple. We split the file using a regular
expression that recognizes macro expansion lines. When we encounter a
macro line, we expand the blocks of the macro in place of the line.</p>
<pre class="csharp"><code class="csharp">		<span class="keyword" id="LiterateCS.BlockBuilder.FromMdFile(string)" data-toggle="tooltip" title="LiterateCS.BlockBuilder.FromMdFile(string)">public</span> <span class="keyword" data-toggle="tooltip" title="LiterateCS.BlockBuilder.FromMdFile(string)">virtual</span> <span class="typename" data-toggle="tooltip" title="LiterateCS.BlockList"><a href="../LiterateCS/BlockList.html#LiterateCS.BlockList">BlockList</a></span> <span data-toggle="tooltip" title="LiterateCS.BlockBuilder.FromMdFile(string)">FromMdFile</span> <span class="punctuation">(</span><span class="keyword" data-toggle="tooltip" title="string">string</span> mdFile<span class="punctuation">)</span>
		<span class="punctuation">{</span>
			<span data-toggle="tooltip" title="string"><a href="../LiterateCS/BlockBuilder.html#LiterateCS.BlockBuilder._currentFile">_currentFile</a></span> <span class="punctuation" data-toggle="tooltip" title="string">=</span> <span data-toggle="tooltip" title="string">mdFile</span><span class="punctuation">;</span>
			<span class="keyword" data-toggle="tooltip" title="string[]">var</span> <span id="parts">parts</span> <span class="punctuation">=</span> <span data-toggle="tooltip" title="System.Text.RegularExpressions.Regex"><a href="../LiterateCS/BlockBuilder.html#LiterateCS.BlockBuilder._macroLine">_macroLine</a></span><span class="punctuation" data-toggle="tooltip" title="System.Text.RegularExpressions.Regex.Split(string)">.</span><span data-toggle="tooltip" title="System.Text.RegularExpressions.Regex.Split(string)">Split</span> <span class="punctuation">(</span><span class="typename" data-toggle="tooltip" title="System.IO.File">File</span><span class="punctuation" data-toggle="tooltip" title="System.IO.File.ReadAllText(string)">.</span><span data-toggle="tooltip" title="System.IO.File.ReadAllText(string)">ReadAllText</span> <span class="punctuation">(</span><span data-toggle="tooltip" title="string">mdFile</span><span class="punctuation">)</span><span class="punctuation">)</span><span class="punctuation">;</span>
			<span class="keyword">foreach</span> <span class="punctuation">(</span><span class="keyword" data-toggle="tooltip" title="string">var</span> part <span class="keyword">in</span> <span data-toggle="tooltip" title="string[]">parts</span><span class="punctuation">)</span>
			<span class="punctuation">{</span>
				<span class="keyword">if</span> <span class="punctuation">(</span><span data-toggle="tooltip" title="string">part</span><span class="punctuation" data-toggle="tooltip" title="string.StartsWith(string)">.</span><span data-toggle="tooltip" title="string.StartsWith(string)">StartsWith</span> <span class="punctuation">(</span><span class="string" data-toggle="tooltip" title="string">&quot;&lt;&lt;&quot;</span><span class="punctuation">)</span> <span class="punctuation" data-toggle="tooltip" title="bool">&amp;&amp;</span> <span data-toggle="tooltip" title="string">part</span><span class="punctuation" data-toggle="tooltip" title="string.EndsWith(string)">.</span><span data-toggle="tooltip" title="string.EndsWith(string)">EndsWith</span> <span class="punctuation">(</span><span class="string" data-toggle="tooltip" title="string">&quot;&gt;&gt;&quot;</span><span class="punctuation">)</span><span class="punctuation">)</span>
				<span class="punctuation">{</span>
					<span class="keyword" data-toggle="tooltip" title="LiterateCS.Macro">var</span> <span id="macro">macro</span> <span class="punctuation">=</span> <span class="typename" data-toggle="tooltip" title="LiterateCS.Macro"><a href="../LiterateCS/Macro.html#LiterateCS.Macro">Macro</a></span><span class="punctuation" data-toggle="tooltip" title="LiterateCS.Macro.Get(string, string)">.</span><span data-toggle="tooltip" title="LiterateCS.Macro.Get(string, string)"><a href="../LiterateCS/Macro.html#LiterateCS.Macro.Get(string, string)">Get</a></span> <span class="punctuation">(</span>
						<span data-toggle="tooltip" title="string">part</span><span class="punctuation" data-toggle="tooltip" title="string.Substring(int, int)">.</span><span data-toggle="tooltip" title="string.Substring(int, int)">Substring</span> <span class="punctuation">(</span><span class="number" data-toggle="tooltip" title="int">2</span><span class="punctuation">,</span> <span data-toggle="tooltip" title="string">part</span><span class="punctuation" data-toggle="tooltip" title="int">.</span><span data-toggle="tooltip" title="int">Length</span> <span class="punctuation" data-toggle="tooltip" title="int">-</span> <span class="number" data-toggle="tooltip" title="int">4</span><span class="punctuation">)</span><span class="punctuation">,</span> <span data-toggle="tooltip" title="string"><a href="../LiterateCS/BlockBuilder.html#LiterateCS.BlockBuilder._currentFile">_currentFile</a></span><span class="punctuation">)</span><span class="punctuation">;</span>
					<span class="keyword">foreach</span> <span class="punctuation">(</span><span class="keyword" data-toggle="tooltip" title="LiterateCS.BlockList">var</span> block <span class="keyword">in</span> <span data-toggle="tooltip" title="LiterateCS.Macro">macro</span><span class="punctuation">)</span>
						<span data-toggle="tooltip" title="LiterateCS.BlockBuilder.AddBlock(LiterateCS.BlockList)"><a href="../LiterateCS/BlockBuilder.html#LiterateCS.BlockBuilder.AddBlock(LiterateCS.BlockList)">AddBlock</a></span> <span class="punctuation">(</span><span class="keyword" data-toggle="tooltip" title="LiterateCS.BlockList">new</span> <span class="typename"><a href="../LiterateCS/BlockList.html#LiterateCS.BlockList">BlockList</a></span> <span class="punctuation">(</span><span data-toggle="tooltip" title="LiterateCS.BlockList">block</span><span class="punctuation">)</span><span class="punctuation">)</span><span class="punctuation">;</span>
				<span class="punctuation">}</span>
				<span class="keyword">else</span>
					<span data-toggle="tooltip" title="LiterateCS.BlockBuilder.AddBlock(LiterateCS.BlockList)"><a href="../LiterateCS/BlockBuilder.html#LiterateCS.BlockBuilder.AddBlock(LiterateCS.BlockList)">AddBlock</a></span> <span class="punctuation">(</span><span class="keyword" data-toggle="tooltip" title="LiterateCS.BlockList">new</span> <span class="typename"><a href="../LiterateCS/BlockList.html#LiterateCS.BlockList">BlockList</a></span> <span class="punctuation">(</span><span data-toggle="tooltip" title="string">part</span><span class="punctuation">)</span><span class="punctuation">)</span><span class="punctuation">;</span>
			<span class="punctuation">}</span>
			<span class="keyword">return</span> <span data-toggle="tooltip" title="LiterateCS.BlockList"><a href="../LiterateCS/BlockBuilder.html#LiterateCS.BlockBuilder._blocks">_blocks</a></span><span class="punctuation">;</span>
		<span class="punctuation">}</span>
</code></pre>
<h3 id="creating-new-blocks">Creating New Blocks</h3>
<p>We can create and initialize a block in one go using the <code>AddBlock</code>
method below.</p>
<pre class="csharp"><code class="csharp">		<span class="keyword" id="LiterateCS.BlockBuilder.AddBlock(LiterateCS.BlockList)" data-toggle="tooltip" title="LiterateCS.BlockBuilder.AddBlock(LiterateCS.BlockList)">public</span> <span class="keyword" data-toggle="tooltip" title="void">void</span> <span data-toggle="tooltip" title="LiterateCS.BlockBuilder.AddBlock(LiterateCS.BlockList)">AddBlock</span> <span class="punctuation">(</span><span class="typename" data-toggle="tooltip" title="LiterateCS.BlockList"><a href="../LiterateCS/BlockList.html#LiterateCS.BlockList">BlockList</a></span> block<span class="punctuation">)</span>
		<span class="punctuation">{</span>
			<span class="keyword">if</span> <span class="punctuation">(</span><span data-toggle="tooltip" title="LiterateCS.BlockList"><a href="../LiterateCS/BlockBuilder.html#LiterateCS.BlockBuilder._blocks">_blocks</a></span> <span class="punctuation" data-toggle="tooltip" title="bool">==</span> <span class="keyword">null</span><span class="punctuation">)</span>
				<span data-toggle="tooltip" title="LiterateCS.BlockList"><a href="../LiterateCS/BlockBuilder.html#LiterateCS.BlockBuilder._blocks">_blocks</a></span> <span class="punctuation" data-toggle="tooltip" title="LiterateCS.BlockList">=</span> <span data-toggle="tooltip" title="LiterateCS.BlockList">block</span><span class="punctuation">;</span>
			<span class="keyword">else</span>
				<span data-toggle="tooltip" title="LiterateCS.BlockList"><a href="../LiterateCS/BlockBuilder.html#LiterateCS.BlockBuilder._currentBlock">_currentBlock</a></span><span class="punctuation" data-toggle="tooltip" title="LiterateCS.BlockList">.</span><span data-toggle="tooltip" title="LiterateCS.BlockList"><a href="../LiterateCS/BlockList.html#LiterateCS.BlockList.Next">Next</a></span> <span class="punctuation" data-toggle="tooltip" title="LiterateCS.BlockList">=</span> <span data-toggle="tooltip" title="LiterateCS.BlockList">block</span><span class="punctuation">;</span>
			<span data-toggle="tooltip" title="LiterateCS.BlockList"><a href="../LiterateCS/BlockBuilder.html#LiterateCS.BlockBuilder._currentBlock">_currentBlock</a></span> <span class="punctuation" data-toggle="tooltip" title="LiterateCS.BlockList">=</span> <span data-toggle="tooltip" title="LiterateCS.BlockList">block</span><span class="punctuation">;</span>
		<span class="punctuation">}</span>
</code></pre>
<p>Alternatively we can build a block incrementally by first creating it
and adding text later. Starting a new block closes the previous one
automatically, if such exists.</p>
<pre class="csharp"><code class="csharp">		<span class="keyword" id="LiterateCS.BlockBuilder.StartNewBlock(LiterateCS.BlockKind)" data-toggle="tooltip" title="LiterateCS.BlockBuilder.StartNewBlock(LiterateCS.BlockKind)">private</span> <span class="keyword" data-toggle="tooltip" title="void">void</span> <span data-toggle="tooltip" title="LiterateCS.BlockBuilder.StartNewBlock(LiterateCS.BlockKind)">StartNewBlock</span> <span class="punctuation">(</span><span class="typename" data-toggle="tooltip" title="LiterateCS.BlockKind"><a href="../LiterateCS/BlockList.html#LiterateCS.BlockKind">BlockKind</a></span> kind<span class="punctuation">)</span>
		<span class="punctuation">{</span>
			<span class="keyword" data-toggle="tooltip" title="LiterateCS.BlockList">var</span> <span id="result">result</span> <span class="punctuation">=</span> <span class="keyword" data-toggle="tooltip" title="LiterateCS.BlockList">new</span> <span class="typename"><a href="../LiterateCS/BlockList.html#LiterateCS.BlockList">BlockList</a></span> <span class="punctuation">(</span><span data-toggle="tooltip" title="LiterateCS.BlockKind">kind</span><span class="punctuation">,</span> <span data-toggle="tooltip" title="LiterateCS.Options"><a href="../LiterateCS/BlockBuilder.html#LiterateCS.BlockBuilder._options">_options</a></span><span class="punctuation" data-toggle="tooltip" title="LiterateCS.OutputFormat">.</span><span data-toggle="tooltip" title="LiterateCS.OutputFormat"><a href="../LiterateCS/Options.html#LiterateCS.Options.Format">Format</a></span><span class="punctuation">)</span><span class="punctuation">;</span>
			<span class="keyword">if</span> <span class="punctuation">(</span><span data-toggle="tooltip" title="LiterateCS.BlockList"><a href="../LiterateCS/BlockBuilder.html#LiterateCS.BlockBuilder._blocks">_blocks</a></span> <span class="punctuation" data-toggle="tooltip" title="bool">==</span> <span class="keyword">null</span><span class="punctuation">)</span>
				<span data-toggle="tooltip" title="LiterateCS.BlockList"><a href="../LiterateCS/BlockBuilder.html#LiterateCS.BlockBuilder._blocks">_blocks</a></span> <span class="punctuation" data-toggle="tooltip" title="LiterateCS.BlockList">=</span> <span data-toggle="tooltip" title="LiterateCS.BlockList">result</span><span class="punctuation">;</span>
			<span class="keyword">else</span>
			<span class="punctuation">{</span>
				<span data-toggle="tooltip" title="LiterateCS.BlockList"><a href="../LiterateCS/BlockBuilder.html#LiterateCS.BlockBuilder._currentBlock">_currentBlock</a></span><span class="punctuation" data-toggle="tooltip" title="LiterateCS.BlockList">.</span><span data-toggle="tooltip" title="LiterateCS.BlockList"><a href="../LiterateCS/BlockList.html#LiterateCS.BlockList.Next">Next</a></span> <span class="punctuation" data-toggle="tooltip" title="LiterateCS.BlockList">=</span> <span data-toggle="tooltip" title="LiterateCS.BlockList">result</span><span class="punctuation">;</span>
				<span data-toggle="tooltip" title="LiterateCS.BlockList"><a href="../LiterateCS/BlockBuilder.html#LiterateCS.BlockBuilder._currentBlock">_currentBlock</a></span><span class="punctuation" data-toggle="tooltip" title="LiterateCS.BlockList.Close(LiterateCS.OutputFormat)">.</span><span data-toggle="tooltip" title="LiterateCS.BlockList.Close(LiterateCS.OutputFormat)"><a href="../LiterateCS/BlockList.html#LiterateCS.BlockList.Close(LiterateCS.OutputFormat)">Close</a></span> <span class="punctuation">(</span><span data-toggle="tooltip" title="LiterateCS.Options"><a href="../LiterateCS/BlockBuilder.html#LiterateCS.BlockBuilder._options">_options</a></span><span class="punctuation" data-toggle="tooltip" title="LiterateCS.OutputFormat">.</span><span data-toggle="tooltip" title="LiterateCS.OutputFormat"><a href="../LiterateCS/Options.html#LiterateCS.Options.Format">Format</a></span><span class="punctuation">)</span><span class="punctuation">;</span>
			<span class="punctuation">}</span>
			<span data-toggle="tooltip" title="LiterateCS.BlockList"><a href="../LiterateCS/BlockBuilder.html#LiterateCS.BlockBuilder._currentBlock">_currentBlock</a></span> <span class="punctuation" data-toggle="tooltip" title="LiterateCS.BlockList">=</span> <span data-toggle="tooltip" title="LiterateCS.BlockList">result</span><span class="punctuation">;</span>
		<span class="punctuation">}</span>
</code></pre>
<p>The helper function below checks if the kind of the current block
matches the kind of the block requested. If it does, the current
block is returned; if not, a new block is started.</p>
<p>A new block is opened also in case the <code>_startNewBlock</code> flag is set.
When this occurs, the flag is reset back to false and a reference
to the opened block is stored in the <code>_newBlock</code> field.</p>
<pre class="csharp"><code class="csharp">		<span class="keyword" id="LiterateCS.BlockBuilder.CurrentBlock(LiterateCS.BlockKind)" data-toggle="tooltip" title="LiterateCS.BlockBuilder.CurrentBlock(LiterateCS.BlockKind)">private</span> <span class="typename" data-toggle="tooltip" title="LiterateCS.BlockList"><a href="../LiterateCS/BlockList.html#LiterateCS.BlockList">BlockList</a></span> <span data-toggle="tooltip" title="LiterateCS.BlockBuilder.CurrentBlock(LiterateCS.BlockKind)">CurrentBlock</span> <span class="punctuation">(</span><span class="typename" data-toggle="tooltip" title="LiterateCS.BlockKind"><a href="../LiterateCS/BlockList.html#LiterateCS.BlockKind">BlockKind</a></span> kind<span class="punctuation">)</span>
		<span class="punctuation">{</span>
			<span class="keyword">if</span> <span class="punctuation">(</span><span data-toggle="tooltip" title="LiterateCS.BlockList"><a href="../LiterateCS/BlockBuilder.html#LiterateCS.BlockBuilder._blocks">_blocks</a></span> <span class="punctuation" data-toggle="tooltip" title="bool">==</span> <span class="keyword">null</span> <span class="punctuation" data-toggle="tooltip" title="bool">||</span> <span data-toggle="tooltip" title="LiterateCS.BlockList"><a href="../LiterateCS/BlockBuilder.html#LiterateCS.BlockBuilder._currentBlock">_currentBlock</a></span><span class="punctuation" data-toggle="tooltip" title="LiterateCS.BlockKind">.</span><span data-toggle="tooltip" title="LiterateCS.BlockKind"><a href="../LiterateCS/BlockList.html#LiterateCS.BlockList.Kind">Kind</a></span> <span class="punctuation" data-toggle="tooltip" title="bool">!=</span> <span data-toggle="tooltip" title="LiterateCS.BlockKind">kind</span> <span class="punctuation" data-toggle="tooltip" title="bool">||</span> <span data-toggle="tooltip" title="bool"><a href="../LiterateCS/BlockBuilder.html#LiterateCS.BlockBuilder._startNewBlock">_startNewBlock</a></span><span class="punctuation">)</span>
				<span data-toggle="tooltip" title="LiterateCS.BlockBuilder.StartNewBlock(LiterateCS.BlockKind)"><a href="../LiterateCS/BlockBuilder.html#LiterateCS.BlockBuilder.StartNewBlock(LiterateCS.BlockKind)">StartNewBlock</a></span> <span class="punctuation">(</span><span data-toggle="tooltip" title="LiterateCS.BlockKind">kind</span><span class="punctuation">)</span><span class="punctuation">;</span>
			<span class="keyword">if</span> <span class="punctuation">(</span><span data-toggle="tooltip" title="bool"><a href="../LiterateCS/BlockBuilder.html#LiterateCS.BlockBuilder._startNewBlock">_startNewBlock</a></span><span class="punctuation">)</span>
			<span class="punctuation">{</span>
				<span data-toggle="tooltip" title="bool"><a href="../LiterateCS/BlockBuilder.html#LiterateCS.BlockBuilder._startNewBlock">_startNewBlock</a></span> <span class="punctuation" data-toggle="tooltip" title="bool">=</span> <span class="keyword" data-toggle="tooltip" title="bool">false</span><span class="punctuation">;</span>
				<span data-toggle="tooltip" title="LiterateCS.BlockList"><a href="../LiterateCS/BlockBuilder.html#LiterateCS.BlockBuilder._newBlock">_newBlock</a></span> <span class="punctuation" data-toggle="tooltip" title="LiterateCS.BlockList">=</span> <span data-toggle="tooltip" title="LiterateCS.BlockList"><a href="../LiterateCS/BlockBuilder.html#LiterateCS.BlockBuilder._currentBlock">_currentBlock</a></span><span class="punctuation">;</span>
			<span class="punctuation">}</span>
			<span class="keyword">return</span> <span data-toggle="tooltip" title="LiterateCS.BlockList"><a href="../LiterateCS/BlockBuilder.html#LiterateCS.BlockBuilder._currentBlock">_currentBlock</a></span><span class="punctuation">;</span>
		<span class="punctuation">}</span>
</code></pre>
<p>Execute methods use the method below to initialize a new block list,
and to run the syntax walker by visiting the root of the tree. After
all the blocks are created, the last block is closed, and the head of
the list is returned.</p>
<pre class="csharp"><code class="csharp">		<span class="keyword" id="LiterateCS.BlockBuilder.CreateForTree(Microsoft.CodeAnalysis.SyntaxTree)" data-toggle="tooltip" title="LiterateCS.BlockBuilder.CreateForTree(Microsoft.CodeAnalysis.SyntaxTree)">private</span> <span class="typename" data-toggle="tooltip" title="LiterateCS.BlockList"><a href="../LiterateCS/BlockList.html#LiterateCS.BlockList">BlockList</a></span> <span data-toggle="tooltip" title="LiterateCS.BlockBuilder.CreateForTree(Microsoft.CodeAnalysis.SyntaxTree)">CreateForTree</span> <span class="punctuation">(</span><span class="typename" data-toggle="tooltip" title="Microsoft.CodeAnalysis.SyntaxTree">SyntaxTree</span> tree<span class="punctuation">)</span>
		<span class="punctuation">{</span>
			<span data-toggle="tooltip" title="LiterateCS.BlockList"><a href="../LiterateCS/BlockBuilder.html#LiterateCS.BlockBuilder._blocks">_blocks</a></span> <span class="punctuation" data-toggle="tooltip" title="LiterateCS.BlockList">=</span> <span class="keyword">null</span><span class="punctuation">;</span>
			<span data-toggle="tooltip" title="Microsoft.CodeAnalysis.CSharp.CSharpSyntaxWalker.Visit(Microsoft.CodeAnalysis.SyntaxNode)">Visit</span> <span class="punctuation">(</span><span data-toggle="tooltip" title="Microsoft.CodeAnalysis.SyntaxTree">tree</span><span class="punctuation" data-toggle="tooltip" title="Microsoft.CodeAnalysis.SyntaxTree.GetRoot(System.Threading.CancellationToken)">.</span><span data-toggle="tooltip" title="Microsoft.CodeAnalysis.SyntaxTree.GetRoot(System.Threading.CancellationToken)">GetRoot</span> <span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">)</span><span class="punctuation">;</span>
			<span data-toggle="tooltip" title="LiterateCS.BlockList"><a href="../LiterateCS/BlockBuilder.html#LiterateCS.BlockBuilder._currentBlock">_currentBlock</a></span><span class="punctuation" data-toggle="tooltip" title="LiterateCS.BlockList.Close(LiterateCS.OutputFormat)">.</span><span data-toggle="tooltip" title="LiterateCS.BlockList.Close(LiterateCS.OutputFormat)"><a href="../LiterateCS/BlockList.html#LiterateCS.BlockList.Close(LiterateCS.OutputFormat)">Close</a></span> <span class="punctuation">(</span><span data-toggle="tooltip" title="LiterateCS.Options"><a href="../LiterateCS/BlockBuilder.html#LiterateCS.BlockBuilder._options">_options</a></span><span class="punctuation" data-toggle="tooltip" title="LiterateCS.OutputFormat">.</span><span data-toggle="tooltip" title="LiterateCS.OutputFormat"><a href="../LiterateCS/Options.html#LiterateCS.Options.Format">Format</a></span><span class="punctuation">)</span><span class="punctuation">;</span>
			<span class="keyword">return</span> <span data-toggle="tooltip" title="LiterateCS.BlockList"><a href="../LiterateCS/BlockBuilder.html#LiterateCS.BlockBuilder._blocks">_blocks</a></span><span class="punctuation">;</span>
		<span class="punctuation">}</span>
</code></pre>
<h3 id="adding-documentation">Adding Documentation</h3>
<p>Appending a piece of markdown into a block would be very straightforward
if we wouldn't need to deal with whitespace. Usually the <code>--trim</code> option
is used to remove the leading whitespace from the comments. This complicates
the code a bit.</p>
<pre class="csharp"><code class="csharp">		<span class="keyword" id="LiterateCS.BlockBuilder.AppendMarkdown(string)" data-toggle="tooltip" title="LiterateCS.BlockBuilder.AppendMarkdown(string)">protected</span> <span class="keyword" data-toggle="tooltip" title="void">void</span> <span data-toggle="tooltip" title="LiterateCS.BlockBuilder.AppendMarkdown(string)">AppendMarkdown</span> <span class="punctuation">(</span><span class="keyword" data-toggle="tooltip" title="string">string</span> text<span class="punctuation">)</span>
		<span class="punctuation">{</span>
			<span class="keyword">if</span> <span class="punctuation">(</span><span data-toggle="tooltip" title="LiterateCS.Options"><a href="../LiterateCS/BlockBuilder.html#LiterateCS.BlockBuilder._options">_options</a></span><span class="punctuation" data-toggle="tooltip" title="bool">.</span><span data-toggle="tooltip" title="bool"><a href="../LiterateCS/Options.html#LiterateCS.Options.Trim">Trim</a></span><span class="punctuation">)</span>
			<span class="punctuation">{</span>
</code></pre>
<p>Trimming starts with splitting the comment block into lines.
We maintain the variable <code>firstNonWS</code> which contains the index
of the first non-whitespace character in the comment block.
Remember that we already removed the comment delimiters from
the text block before calling this function.</p>
<pre class="csharp"><code class="csharp">				<span class="keyword" data-toggle="tooltip" title="int">var</span> <span id="firstNonWS">firstNonWS</span> <span class="punctuation">=</span> <span class="punctuation" data-toggle="tooltip" title="int">-</span><span class="number" data-toggle="tooltip" title="int">1</span><span class="punctuation">;</span>
				<span class="keyword">foreach</span> <span class="punctuation">(</span><span class="keyword" data-toggle="tooltip" title="string">var</span> line <span class="keyword">in</span> <span class="typename" data-toggle="tooltip" title="System.Text.RegularExpressions.Regex">Regex</span><span class="punctuation" data-toggle="tooltip" title="System.Text.RegularExpressions.Regex.Split(string, string)">.</span><span data-toggle="tooltip" title="System.Text.RegularExpressions.Regex.Split(string, string)">Split</span> <span class="punctuation">(</span><span data-toggle="tooltip" title="string">text</span><span class="punctuation">,</span> <span class="string" data-toggle="tooltip" title="string">&quot;\r\n|\r|\n&quot;</span><span class="punctuation">)</span><span class="punctuation">)</span>
				<span class="punctuation">{</span>
					<span class="keyword">if</span> <span class="punctuation">(</span><span data-toggle="tooltip" title="int">firstNonWS</span> <span class="punctuation" data-toggle="tooltip" title="bool">&lt;</span> <span class="number" data-toggle="tooltip" title="int">0</span><span class="punctuation">)</span>
					<span class="punctuation">{</span>
						<span class="keyword" data-toggle="tooltip" title="int">var</span> <span id="i">i</span> <span class="punctuation">=</span> <span data-toggle="tooltip" title="string">line</span><span class="punctuation" data-toggle="tooltip" title="System.Collections.Generic.IEnumerable<char>.TakeWhile<char>(System.Func<char, bool>)">.</span><span data-toggle="tooltip" title="System.Collections.Generic.IEnumerable<char>.TakeWhile<char>(System.Func<char, bool>)">TakeWhile</span> <span class="punctuation">(</span><span class="keyword" data-toggle="tooltip" title="char">char</span><span class="punctuation" data-toggle="tooltip" title="char.IsWhiteSpace(char)">.</span><span data-toggle="tooltip" title="char.IsWhiteSpace(char)">IsWhiteSpace</span><span class="punctuation">)</span><span class="punctuation" data-toggle="tooltip" title="System.Collections.Generic.IEnumerable<char>.Count<char>()">.</span><span data-toggle="tooltip" title="System.Collections.Generic.IEnumerable<char>.Count<char>()">Count</span> <span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">;</span>
						<span class="keyword">if</span> <span class="punctuation">(</span><span data-toggle="tooltip" title="int">i</span> <span class="punctuation" data-toggle="tooltip" title="bool">&lt;</span> <span data-toggle="tooltip" title="string">line</span><span class="punctuation" data-toggle="tooltip" title="int">.</span><span data-toggle="tooltip" title="int">Length</span><span class="punctuation">)</span>
							<span data-toggle="tooltip" title="int">firstNonWS</span> <span class="punctuation" data-toggle="tooltip" title="int">=</span> <span data-toggle="tooltip" title="int">i</span><span class="punctuation">;</span>
					<span class="punctuation">}</span>
</code></pre>
<p>If the index of the first non-whitespace character is found,
we extract a substring of the line starting from the index.
If not, we add the whole line into the block.</p>
<pre class="csharp"><code class="csharp">					<span data-toggle="tooltip" title="LiterateCS.BlockBuilder.CurrentBlock(LiterateCS.BlockKind)"><a href="../LiterateCS/BlockBuilder.html#LiterateCS.BlockBuilder.CurrentBlock(LiterateCS.BlockKind)">CurrentBlock</a></span> <span class="punctuation">(</span><span class="typename" data-toggle="tooltip" title="LiterateCS.BlockKind"><a href="../LiterateCS/BlockList.html#LiterateCS.BlockKind">BlockKind</a></span><span class="punctuation" data-toggle="tooltip" title="LiterateCS.BlockKind">.</span><span data-toggle="tooltip" title="LiterateCS.BlockKind"><a href="../LiterateCS/BlockList.html#LiterateCS.BlockKind.Markdown">Markdown</a></span><span class="punctuation">)</span><span class="punctuation" data-toggle="tooltip" title="System.Text.StringBuilder">.</span><span data-toggle="tooltip" title="System.Text.StringBuilder"><a href="../LiterateCS/BlockList.html#LiterateCS.BlockList._builder">_builder</a></span><span class="punctuation" data-toggle="tooltip" title="System.Text.StringBuilder.AppendLine(string)">.</span><span data-toggle="tooltip" title="System.Text.StringBuilder.AppendLine(string)">AppendLine</span> <span class="punctuation">(</span>
						<span data-toggle="tooltip" title="int">firstNonWS</span> <span class="punctuation" data-toggle="tooltip" title="bool">&lt;</span> <span class="number" data-toggle="tooltip" title="int">0</span> <span class="punctuation" data-toggle="tooltip" title="bool">||</span> <span data-toggle="tooltip" title="string">line</span><span class="punctuation" data-toggle="tooltip" title="int">.</span><span data-toggle="tooltip" title="int">Length</span> <span class="punctuation" data-toggle="tooltip" title="bool">&lt;</span> <span data-toggle="tooltip" title="int">firstNonWS</span> <span class="punctuation" data-toggle="tooltip" title="string">?</span>
							<span data-toggle="tooltip" title="string">line</span> <span class="punctuation" data-toggle="tooltip" title="string">:</span>
							<span data-toggle="tooltip" title="string">line</span><span class="punctuation" data-toggle="tooltip" title="string.Substring(int)">.</span><span data-toggle="tooltip" title="string.Substring(int)">Substring</span> <span class="punctuation">(</span><span data-toggle="tooltip" title="int">firstNonWS</span><span class="punctuation">)</span><span class="punctuation">)</span><span class="punctuation">;</span>
				<span class="punctuation">}</span>
			<span class="punctuation">}</span>
</code></pre>
<p>If the trimming option is not used then we add the whole comment
text as-is into the markdown block.</p>
<pre class="csharp"><code class="csharp">			<span class="keyword">else</span>
				<span data-toggle="tooltip" title="LiterateCS.BlockBuilder.CurrentBlock(LiterateCS.BlockKind)"><a href="../LiterateCS/BlockBuilder.html#LiterateCS.BlockBuilder.CurrentBlock(LiterateCS.BlockKind)">CurrentBlock</a></span> <span class="punctuation">(</span><span class="typename" data-toggle="tooltip" title="LiterateCS.BlockKind"><a href="../LiterateCS/BlockList.html#LiterateCS.BlockKind">BlockKind</a></span><span class="punctuation" data-toggle="tooltip" title="LiterateCS.BlockKind">.</span><span data-toggle="tooltip" title="LiterateCS.BlockKind"><a href="../LiterateCS/BlockList.html#LiterateCS.BlockKind.Markdown">Markdown</a></span><span class="punctuation">)</span><span class="punctuation" data-toggle="tooltip" title="System.Text.StringBuilder">.</span><span data-toggle="tooltip" title="System.Text.StringBuilder"><a href="../LiterateCS/BlockList.html#LiterateCS.BlockList._builder">_builder</a></span><span class="punctuation" data-toggle="tooltip" title="System.Text.StringBuilder.Append(string)">.</span><span data-toggle="tooltip" title="System.Text.StringBuilder.Append(string)">Append</span> <span class="punctuation">(</span><span data-toggle="tooltip" title="string">text</span><span class="punctuation">)</span><span class="punctuation">;</span>
		<span class="punctuation">}</span>
</code></pre>
<h3 id="adding-code">Adding Code</h3>
<p><code>AppendCode</code> adds text to a code block. Unlike comment text, code is
always added one token at a time. So, no multi-line strings are passed
to this function.</p>
<pre class="csharp"><code class="csharp">		<span class="keyword" id="LiterateCS.BlockBuilder.AppendCode(string)" data-toggle="tooltip" title="LiterateCS.BlockBuilder.AppendCode(string)">protected</span> <span class="keyword" data-toggle="tooltip" title="void">void</span> <span data-toggle="tooltip" title="LiterateCS.BlockBuilder.AppendCode(string)">AppendCode</span> <span class="punctuation">(</span><span class="keyword" data-toggle="tooltip" title="string">string</span> text<span class="punctuation">)</span>
		<span class="punctuation">{</span>
			<span data-toggle="tooltip" title="LiterateCS.BlockBuilder.CurrentBlock(LiterateCS.BlockKind)"><a href="../LiterateCS/BlockBuilder.html#LiterateCS.BlockBuilder.CurrentBlock(LiterateCS.BlockKind)">CurrentBlock</a></span> <span class="punctuation">(</span><span class="typename" data-toggle="tooltip" title="LiterateCS.BlockKind"><a href="../LiterateCS/BlockList.html#LiterateCS.BlockKind">BlockKind</a></span><span class="punctuation" data-toggle="tooltip" title="LiterateCS.BlockKind">.</span><span data-toggle="tooltip" title="LiterateCS.BlockKind"><a href="../LiterateCS/BlockList.html#LiterateCS.BlockKind.Code">Code</a></span><span class="punctuation">)</span><span class="punctuation" data-toggle="tooltip" title="System.Text.StringBuilder">.</span><span data-toggle="tooltip" title="System.Text.StringBuilder"><a href="../LiterateCS/BlockList.html#LiterateCS.BlockList._builder">_builder</a></span><span class="punctuation" data-toggle="tooltip" title="System.Text.StringBuilder.Append(string)">.</span><span data-toggle="tooltip" title="System.Text.StringBuilder.Append(string)">Append</span> <span class="punctuation">(</span><span data-toggle="tooltip" title="string">text</span><span class="punctuation">)</span><span class="punctuation">;</span>
		<span class="punctuation">}</span>
</code></pre>
<h2 id="parsing-comments">Parsing Comments</h2>
<p>Removing comment delimiters is easy. The regular expression defined at the
start of the class does the work for us.</p>
<pre class="csharp"><code class="csharp">		<span class="keyword" id="LiterateCS.BlockBuilder.StripCommentDelimiters(string)" data-toggle="tooltip" title="LiterateCS.BlockBuilder.StripCommentDelimiters(string)">private</span> <span class="keyword" data-toggle="tooltip" title="string">string</span> <span data-toggle="tooltip" title="LiterateCS.BlockBuilder.StripCommentDelimiters(string)">StripCommentDelimiters</span> <span class="punctuation">(</span><span class="keyword" data-toggle="tooltip" title="string">string</span> comment<span class="punctuation">)</span> <span class="punctuation">=&gt;</span>
			<span data-toggle="tooltip" title="System.Text.RegularExpressions.Regex"><a href="../LiterateCS/BlockBuilder.html#LiterateCS.BlockBuilder._commentBody">_commentBody</a></span><span class="punctuation" data-toggle="tooltip" title="System.Text.RegularExpressions.Regex.Match(string)">.</span><span data-toggle="tooltip" title="System.Text.RegularExpressions.Regex.Match(string)">Match</span> <span class="punctuation">(</span><span data-toggle="tooltip" title="string">comment</span><span class="punctuation">)</span><span class="punctuation" data-toggle="tooltip" title="System.Text.RegularExpressions.GroupCollection">.</span><span data-toggle="tooltip" title="System.Text.RegularExpressions.GroupCollection">Groups</span><span class="punctuation">[</span><span class="number" data-toggle="tooltip" title="int">1</span><span class="punctuation">]</span><span class="punctuation" data-toggle="tooltip" title="string">.</span><span data-toggle="tooltip" title="string">Value</span><span class="punctuation" data-toggle="tooltip" title="LiterateCS.BlockBuilder.StripCommentDelimiters(string)">;</span>
</code></pre>
<h2 id="parsing-tokens">Parsing Tokens</h2>
<p>Now that we have all the helper functions defined, we can implement the
visitor for tokens. The visitor overrides the inherited method and outputs
text to the current block based on the tokens.</p>
<p>Roslyn parser does not add comments to AST as syntactic nodes. Instead
they are included as trivia which is additional information attached to
tokens. Trivia can be present before and/or after a token, so we have both
leading and trailing trivia. In addition to comments, trivia can represent
also whitespace or preprocessor directives.</p>
<pre class="csharp"><code class="csharp">		<span class="keyword" id="LiterateCS.BlockBuilder.VisitToken(Microsoft.CodeAnalysis.SyntaxToken)" data-toggle="tooltip" title="LiterateCS.BlockBuilder.VisitToken(Microsoft.CodeAnalysis.SyntaxToken)">public</span> <span class="keyword" data-toggle="tooltip" title="LiterateCS.BlockBuilder.VisitToken(Microsoft.CodeAnalysis.SyntaxToken)">override</span> <span class="keyword" data-toggle="tooltip" title="void">void</span> <span data-toggle="tooltip" title="LiterateCS.BlockBuilder.VisitToken(Microsoft.CodeAnalysis.SyntaxToken)">VisitToken</span> <span class="punctuation">(</span><span class="typename" data-toggle="tooltip" title="Microsoft.CodeAnalysis.SyntaxToken">SyntaxToken</span> token<span class="punctuation">)</span>
		<span class="punctuation">{</span>
</code></pre>
<p>First we process the leading trivia.</p>
<pre class="csharp"><code class="csharp">			<span data-toggle="tooltip" title="LiterateCS.BlockBuilder.ProcessTrivia(Microsoft.CodeAnalysis.SyntaxTriviaList)"><a href="../LiterateCS/BlockBuilder.html#LiterateCS.BlockBuilder.ProcessTrivia(Microsoft.CodeAnalysis.SyntaxTriviaList)">ProcessTrivia</a></span> <span class="punctuation">(</span><span data-toggle="tooltip" title="Microsoft.CodeAnalysis.SyntaxToken">token</span><span class="punctuation" data-toggle="tooltip" title="Microsoft.CodeAnalysis.SyntaxTriviaList">.</span><span data-toggle="tooltip" title="Microsoft.CodeAnalysis.SyntaxTriviaList">LeadingTrivia</span><span class="punctuation">)</span><span class="punctuation">;</span>
</code></pre>
<p>Then we output the token itself as code. We skip the end-of-file
token in order not output an empty code block at the end page.</p>
<pre class="csharp"><code class="csharp">			<span class="keyword">if</span> <span class="punctuation">(</span><span data-toggle="tooltip" title="Microsoft.CodeAnalysis.SyntaxToken">token</span><span class="punctuation" data-toggle="tooltip" title="Microsoft.CodeAnalysis.SyntaxToken.Kind()">.</span><span data-toggle="tooltip" title="Microsoft.CodeAnalysis.SyntaxToken.Kind()">Kind</span> <span class="punctuation">(</span><span class="punctuation">)</span> <span class="punctuation" data-toggle="tooltip" title="bool">!=</span> <span class="typename" data-toggle="tooltip" title="Microsoft.CodeAnalysis.CSharp.SyntaxKind">SyntaxKind</span><span class="punctuation" data-toggle="tooltip" title="Microsoft.CodeAnalysis.CSharp.SyntaxKind">.</span><span data-toggle="tooltip" title="Microsoft.CodeAnalysis.CSharp.SyntaxKind">EndOfFileToken</span><span class="punctuation">)</span>
				<span data-toggle="tooltip" title="LiterateCS.BlockBuilder.OutputToken(Microsoft.CodeAnalysis.SyntaxToken)"><a href="../LiterateCS/BlockBuilder.html#LiterateCS.BlockBuilder.OutputToken(Microsoft.CodeAnalysis.SyntaxToken)">OutputToken</a></span> <span class="punctuation">(</span><span data-toggle="tooltip" title="Microsoft.CodeAnalysis.SyntaxToken">token</span><span class="punctuation">)</span><span class="punctuation">;</span>
</code></pre>
<p>And then we output the trailing trivia.</p>
<pre class="csharp"><code class="csharp">			<span data-toggle="tooltip" title="LiterateCS.BlockBuilder.ProcessTrivia(Microsoft.CodeAnalysis.SyntaxTriviaList)"><a href="../LiterateCS/BlockBuilder.html#LiterateCS.BlockBuilder.ProcessTrivia(Microsoft.CodeAnalysis.SyntaxTriviaList)">ProcessTrivia</a></span> <span class="punctuation">(</span><span data-toggle="tooltip" title="Microsoft.CodeAnalysis.SyntaxToken">token</span><span class="punctuation" data-toggle="tooltip" title="Microsoft.CodeAnalysis.SyntaxTriviaList">.</span><span data-toggle="tooltip" title="Microsoft.CodeAnalysis.SyntaxTriviaList">TrailingTrivia</span><span class="punctuation">)</span><span class="punctuation">;</span>
</code></pre>
<p>We must call the inherited method to visit the <code>#region</code> directives
which reside under tokens in AST.</p>
<pre class="csharp"><code class="csharp">			<span class="keyword" data-toggle="tooltip" title="Microsoft.CodeAnalysis.CSharp.CSharpSyntaxWalker">base</span><span class="punctuation" data-toggle="tooltip" title="Microsoft.CodeAnalysis.CSharp.CSharpSyntaxWalker.VisitToken(Microsoft.CodeAnalysis.SyntaxToken)">.</span><span data-toggle="tooltip" title="Microsoft.CodeAnalysis.CSharp.CSharpSyntaxWalker.VisitToken(Microsoft.CodeAnalysis.SyntaxToken)">VisitToken</span> <span class="punctuation">(</span><span data-toggle="tooltip" title="Microsoft.CodeAnalysis.SyntaxToken">token</span><span class="punctuation">)</span><span class="punctuation">;</span>
		<span class="punctuation">}</span>
</code></pre>
<p>The method below processes a list of trivia.</p>
<pre class="csharp"><code class="csharp">		<span class="keyword" id="LiterateCS.BlockBuilder.ProcessTrivia(Microsoft.CodeAnalysis.SyntaxTriviaList)" data-toggle="tooltip" title="LiterateCS.BlockBuilder.ProcessTrivia(Microsoft.CodeAnalysis.SyntaxTriviaList)">private</span> <span class="keyword" data-toggle="tooltip" title="void">void</span> <span data-toggle="tooltip" title="LiterateCS.BlockBuilder.ProcessTrivia(Microsoft.CodeAnalysis.SyntaxTriviaList)">ProcessTrivia</span> <span class="punctuation">(</span><span class="typename" data-toggle="tooltip" title="Microsoft.CodeAnalysis.SyntaxTriviaList">SyntaxTriviaList</span> trivia<span class="punctuation">)</span>
		<span class="punctuation">{</span>
			<span class="keyword">for</span> <span class="punctuation">(</span><span class="keyword" data-toggle="tooltip" title="int">var</span> i <span class="punctuation">=</span> <span class="number" data-toggle="tooltip" title="int">0</span><span class="punctuation">;</span> <span data-toggle="tooltip" title="int">i</span> <span class="punctuation" data-toggle="tooltip" title="bool">&lt;</span> <span data-toggle="tooltip" title="Microsoft.CodeAnalysis.SyntaxTriviaList">trivia</span><span class="punctuation" data-toggle="tooltip" title="int">.</span><span data-toggle="tooltip" title="int">Count</span><span class="punctuation">;</span> <span data-toggle="tooltip" title="int">i</span><span class="punctuation" data-toggle="tooltip" title="int">++</span><span class="punctuation">)</span>
			<span class="punctuation">{</span>
				<span class="keyword">switch</span> <span class="punctuation">(</span><span data-toggle="tooltip" title="Microsoft.CodeAnalysis.SyntaxTriviaList">trivia</span><span class="punctuation">[</span><span data-toggle="tooltip" title="int">i</span><span class="punctuation">]</span><span class="punctuation" data-toggle="tooltip" title="Microsoft.CodeAnalysis.SyntaxTrivia.Kind()">.</span><span data-toggle="tooltip" title="Microsoft.CodeAnalysis.SyntaxTrivia.Kind()">Kind</span> <span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">)</span>
				<span class="punctuation">{</span>
</code></pre>
<p>If the trivia contains multi-line comment, we will output it as
documentation. Before doing that, we need to strip the comment
delimiters from it.</p>
<pre class="csharp"><code class="csharp">					<span class="keyword">case</span> <span class="typename" data-toggle="tooltip" title="Microsoft.CodeAnalysis.CSharp.SyntaxKind">SyntaxKind</span><span class="punctuation" data-toggle="tooltip" title="Microsoft.CodeAnalysis.CSharp.SyntaxKind">.</span><span data-toggle="tooltip" title="Microsoft.CodeAnalysis.CSharp.SyntaxKind">MultiLineCommentTrivia</span><span class="punctuation">:</span>
						<span data-toggle="tooltip" title="LiterateCS.BlockBuilder.AppendMarkdown(string)"><a href="../LiterateCS/BlockBuilder.html#LiterateCS.BlockBuilder.AppendMarkdown(string)">AppendMarkdown</a></span> <span class="punctuation">(</span><span data-toggle="tooltip" title="LiterateCS.BlockBuilder.StripCommentDelimiters(string)"><a href="../LiterateCS/BlockBuilder.html#LiterateCS.BlockBuilder.StripCommentDelimiters(string)">StripCommentDelimiters</a></span> <span class="punctuation">(</span><span data-toggle="tooltip" title="Microsoft.CodeAnalysis.SyntaxTriviaList">trivia</span><span class="punctuation" data-toggle="tooltip" title="Microsoft.CodeAnalysis.SyntaxTriviaList.ToString()">.</span><span data-toggle="tooltip" title="Microsoft.CodeAnalysis.SyntaxTriviaList.ToString()">ToString</span> <span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">)</span><span class="punctuation">)</span><span class="punctuation">;</span>
						<span class="keyword">break</span><span class="punctuation">;</span>
</code></pre>
<p>Whitespace and eol markers are skipped if they preceed or follow
trivia that we don't want to output. The <code>IsSkippedTrivia</code> function
decides whether a piece of trivia is outputted or not.</p>
<pre class="csharp"><code class="csharp">					<span class="keyword">case</span> <span class="typename" data-toggle="tooltip" title="Microsoft.CodeAnalysis.CSharp.SyntaxKind">SyntaxKind</span><span class="punctuation" data-toggle="tooltip" title="Microsoft.CodeAnalysis.CSharp.SyntaxKind">.</span><span data-toggle="tooltip" title="Microsoft.CodeAnalysis.CSharp.SyntaxKind">WhitespaceTrivia</span><span class="punctuation">:</span>
						<span class="keyword">if</span> <span class="punctuation">(</span><span data-toggle="tooltip" title="int">i</span> <span class="punctuation" data-toggle="tooltip" title="bool">==</span> <span data-toggle="tooltip" title="Microsoft.CodeAnalysis.SyntaxTriviaList">trivia</span><span class="punctuation" data-toggle="tooltip" title="int">.</span><span data-toggle="tooltip" title="int">Count</span> <span class="punctuation" data-toggle="tooltip" title="int">-</span> <span class="number" data-toggle="tooltip" title="int">1</span> <span class="punctuation" data-toggle="tooltip" title="bool">||</span>
							<span class="punctuation" data-toggle="tooltip" title="bool">!</span><span data-toggle="tooltip" title="LiterateCS.BlockBuilder.IsSkippedTrivia(Microsoft.CodeAnalysis.CSharp.SyntaxKind)"><a href="../LiterateCS/BlockBuilder.html#LiterateCS.BlockBuilder.IsSkippedTrivia(Microsoft.CodeAnalysis.CSharp.SyntaxKind)">IsSkippedTrivia</a></span> <span class="punctuation">(</span><span data-toggle="tooltip" title="Microsoft.CodeAnalysis.SyntaxTriviaList">trivia</span><span class="punctuation">[</span><span data-toggle="tooltip" title="int">i</span> <span class="punctuation" data-toggle="tooltip" title="int">+</span> <span class="number" data-toggle="tooltip" title="int">1</span><span class="punctuation">]</span><span class="punctuation" data-toggle="tooltip" title="Microsoft.CodeAnalysis.SyntaxTrivia.Kind()">.</span><span data-toggle="tooltip" title="Microsoft.CodeAnalysis.SyntaxTrivia.Kind()">Kind</span> <span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">)</span><span class="punctuation">)</span>
							<span data-toggle="tooltip" title="LiterateCS.BlockBuilder.OutputTrivia(Microsoft.CodeAnalysis.SyntaxTrivia)"><a href="../LiterateCS/BlockBuilder.html#LiterateCS.BlockBuilder.OutputTrivia(Microsoft.CodeAnalysis.SyntaxTrivia)">OutputTrivia</a></span> <span class="punctuation">(</span><span data-toggle="tooltip" title="Microsoft.CodeAnalysis.SyntaxTriviaList">trivia</span><span class="punctuation">[</span><span data-toggle="tooltip" title="int">i</span><span class="punctuation">]</span><span class="punctuation">)</span><span class="punctuation">;</span>
						<span class="keyword">break</span><span class="punctuation">;</span>
					<span class="keyword">case</span> <span class="typename" data-toggle="tooltip" title="Microsoft.CodeAnalysis.CSharp.SyntaxKind">SyntaxKind</span><span class="punctuation" data-toggle="tooltip" title="Microsoft.CodeAnalysis.CSharp.SyntaxKind">.</span><span data-toggle="tooltip" title="Microsoft.CodeAnalysis.CSharp.SyntaxKind">EndOfLineTrivia</span><span class="punctuation">:</span>
						<span class="keyword">if</span> <span class="punctuation">(</span><span data-toggle="tooltip" title="int">i</span> <span class="punctuation" data-toggle="tooltip" title="bool">==</span> <span class="number" data-toggle="tooltip" title="int">0</span> <span class="punctuation" data-toggle="tooltip" title="bool">||</span>
							<span class="punctuation" data-toggle="tooltip" title="bool">!</span><span data-toggle="tooltip" title="LiterateCS.BlockBuilder.IsSkippedTrivia(Microsoft.CodeAnalysis.CSharp.SyntaxKind)"><a href="../LiterateCS/BlockBuilder.html#LiterateCS.BlockBuilder.IsSkippedTrivia(Microsoft.CodeAnalysis.CSharp.SyntaxKind)">IsSkippedTrivia</a></span> <span class="punctuation">(</span><span data-toggle="tooltip" title="Microsoft.CodeAnalysis.SyntaxTriviaList">trivia</span><span class="punctuation">[</span><span data-toggle="tooltip" title="int">i</span> <span class="punctuation" data-toggle="tooltip" title="int">-</span> <span class="number" data-toggle="tooltip" title="int">1</span><span class="punctuation">]</span><span class="punctuation" data-toggle="tooltip" title="Microsoft.CodeAnalysis.SyntaxTrivia.Kind()">.</span><span data-toggle="tooltip" title="Microsoft.CodeAnalysis.SyntaxTrivia.Kind()">Kind</span> <span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">)</span><span class="punctuation">)</span>
							<span data-toggle="tooltip" title="LiterateCS.BlockBuilder.OutputTrivia(Microsoft.CodeAnalysis.SyntaxTrivia)"><a href="../LiterateCS/BlockBuilder.html#LiterateCS.BlockBuilder.OutputTrivia(Microsoft.CodeAnalysis.SyntaxTrivia)">OutputTrivia</a></span> <span class="punctuation">(</span><span data-toggle="tooltip" title="Microsoft.CodeAnalysis.SyntaxTriviaList">trivia</span><span class="punctuation">[</span><span data-toggle="tooltip" title="int">i</span><span class="punctuation">]</span><span class="punctuation">)</span><span class="punctuation">;</span>
						<span class="keyword">break</span><span class="punctuation">;</span>
</code></pre>
<p>When we encounter either <code>#region</code> or <code>#endregion</code> directive, we
start a new block. The <code>VisitRegionDirectiveTrivia</code> visitor method
actually creates the new macro. Note that we omit the directives
in the output altogether.</p>
<pre class="csharp"><code class="csharp">					<span class="keyword">case</span> <span class="typename" data-toggle="tooltip" title="Microsoft.CodeAnalysis.CSharp.SyntaxKind">SyntaxKind</span><span class="punctuation" data-toggle="tooltip" title="Microsoft.CodeAnalysis.CSharp.SyntaxKind">.</span><span data-toggle="tooltip" title="Microsoft.CodeAnalysis.CSharp.SyntaxKind">RegionDirectiveTrivia</span><span class="punctuation">:</span>
					<span class="keyword">case</span> <span class="typename" data-toggle="tooltip" title="Microsoft.CodeAnalysis.CSharp.SyntaxKind">SyntaxKind</span><span class="punctuation" data-toggle="tooltip" title="Microsoft.CodeAnalysis.CSharp.SyntaxKind">.</span><span data-toggle="tooltip" title="Microsoft.CodeAnalysis.CSharp.SyntaxKind">EndRegionDirectiveTrivia</span><span class="punctuation">:</span>
						<span data-toggle="tooltip" title="bool"><a href="../LiterateCS/BlockBuilder.html#LiterateCS.BlockBuilder._startNewBlock">_startNewBlock</a></span> <span class="punctuation" data-toggle="tooltip" title="bool">=</span> <span class="keyword" data-toggle="tooltip" title="bool">true</span><span class="punctuation">;</span>
						<span class="keyword">break</span><span class="punctuation">;</span>
</code></pre>
<p>In case of any other trivia we revert to the generic method which
outputs it verbatim as code.</p>
<pre class="csharp"><code class="csharp">					<span class="keyword">default</span><span class="punctuation">:</span>
						<span data-toggle="tooltip" title="LiterateCS.BlockBuilder.OutputTrivia(Microsoft.CodeAnalysis.SyntaxTrivia)"><a href="../LiterateCS/BlockBuilder.html#LiterateCS.BlockBuilder.OutputTrivia(Microsoft.CodeAnalysis.SyntaxTrivia)">OutputTrivia</a></span> <span class="punctuation">(</span><span data-toggle="tooltip" title="Microsoft.CodeAnalysis.SyntaxTriviaList">trivia</span><span class="punctuation">[</span><span data-toggle="tooltip" title="int">i</span><span class="punctuation">]</span><span class="punctuation">)</span><span class="punctuation">;</span>
						<span class="keyword">break</span><span class="punctuation">;</span>
				<span class="punctuation">}</span>
			<span class="punctuation">}</span>
		<span class="punctuation">}</span>
</code></pre>
<p>As explained above, this helper function checks whether we want to
output a certain kind of trivia (as code) or not.</p>
<pre class="csharp"><code class="csharp">		<span class="keyword" id="LiterateCS.BlockBuilder.IsSkippedTrivia(Microsoft.CodeAnalysis.CSharp.SyntaxKind)" data-toggle="tooltip" title="LiterateCS.BlockBuilder.IsSkippedTrivia(Microsoft.CodeAnalysis.CSharp.SyntaxKind)">private</span> <span class="keyword" data-toggle="tooltip" title="bool">bool</span> <span data-toggle="tooltip" title="LiterateCS.BlockBuilder.IsSkippedTrivia(Microsoft.CodeAnalysis.CSharp.SyntaxKind)">IsSkippedTrivia</span> <span class="punctuation">(</span><span class="typename" data-toggle="tooltip" title="Microsoft.CodeAnalysis.CSharp.SyntaxKind">SyntaxKind</span> kind<span class="punctuation">)</span>
		<span class="punctuation">{</span>
			<span class="keyword">return</span> <span data-toggle="tooltip" title="Microsoft.CodeAnalysis.CSharp.SyntaxKind">kind</span><span class="punctuation" data-toggle="tooltip" title="Microsoft.CodeAnalysis.CSharp.SyntaxKind.In<Microsoft.CodeAnalysis.CSharp.SyntaxKind>(params Microsoft.CodeAnalysis.CSharp.SyntaxKind[])">.</span><span data-toggle="tooltip" title="Microsoft.CodeAnalysis.CSharp.SyntaxKind.In<Microsoft.CodeAnalysis.CSharp.SyntaxKind>(params Microsoft.CodeAnalysis.CSharp.SyntaxKind[])">In</span> <span class="punctuation">(</span>
				<span class="typename" data-toggle="tooltip" title="Microsoft.CodeAnalysis.CSharp.SyntaxKind">SyntaxKind</span><span class="punctuation" data-toggle="tooltip" title="Microsoft.CodeAnalysis.CSharp.SyntaxKind">.</span><span data-toggle="tooltip" title="Microsoft.CodeAnalysis.CSharp.SyntaxKind">RegionDirectiveTrivia</span><span class="punctuation">,</span>
				<span class="typename" data-toggle="tooltip" title="Microsoft.CodeAnalysis.CSharp.SyntaxKind">SyntaxKind</span><span class="punctuation" data-toggle="tooltip" title="Microsoft.CodeAnalysis.CSharp.SyntaxKind">.</span><span data-toggle="tooltip" title="Microsoft.CodeAnalysis.CSharp.SyntaxKind">EndRegionDirectiveTrivia</span><span class="punctuation">,</span>
				<span class="typename" data-toggle="tooltip" title="Microsoft.CodeAnalysis.CSharp.SyntaxKind">SyntaxKind</span><span class="punctuation" data-toggle="tooltip" title="Microsoft.CodeAnalysis.CSharp.SyntaxKind">.</span><span data-toggle="tooltip" title="Microsoft.CodeAnalysis.CSharp.SyntaxKind">MultiLineCommentTrivia</span><span class="punctuation">)</span><span class="punctuation">;</span>
		<span class="punctuation">}</span>
</code></pre>
<p>The following two methods are virtual so that subclasses can alter their
behavior. The first one outputs a token, and the second one a piece of
trivia. Both methods just send the text verbatim to the current code block.</p>
<pre class="csharp"><code class="csharp">		<span class="keyword" id="LiterateCS.BlockBuilder.OutputToken(Microsoft.CodeAnalysis.SyntaxToken)" data-toggle="tooltip" title="LiterateCS.BlockBuilder.OutputToken(Microsoft.CodeAnalysis.SyntaxToken)">protected</span> <span class="keyword" data-toggle="tooltip" title="LiterateCS.BlockBuilder.OutputToken(Microsoft.CodeAnalysis.SyntaxToken)">virtual</span> <span class="keyword" data-toggle="tooltip" title="void">void</span> <span data-toggle="tooltip" title="LiterateCS.BlockBuilder.OutputToken(Microsoft.CodeAnalysis.SyntaxToken)">OutputToken</span> <span class="punctuation">(</span><span class="typename" data-toggle="tooltip" title="Microsoft.CodeAnalysis.SyntaxToken">SyntaxToken</span> token<span class="punctuation">)</span>
		<span class="punctuation">{</span>
			<span data-toggle="tooltip" title="LiterateCS.BlockBuilder.AppendCode(string)"><a href="../LiterateCS/BlockBuilder.html#LiterateCS.BlockBuilder.AppendCode(string)">AppendCode</a></span> <span class="punctuation">(</span><span data-toggle="tooltip" title="Microsoft.CodeAnalysis.SyntaxToken">token</span><span class="punctuation" data-toggle="tooltip" title="Microsoft.CodeAnalysis.SyntaxToken.ToString()">.</span><span data-toggle="tooltip" title="Microsoft.CodeAnalysis.SyntaxToken.ToString()">ToString</span> <span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">)</span><span class="punctuation">;</span>
		<span class="punctuation">}</span>

		<span class="keyword" id="LiterateCS.BlockBuilder.OutputTrivia(Microsoft.CodeAnalysis.SyntaxTrivia)" data-toggle="tooltip" title="LiterateCS.BlockBuilder.OutputTrivia(Microsoft.CodeAnalysis.SyntaxTrivia)">protected</span> <span class="keyword" data-toggle="tooltip" title="LiterateCS.BlockBuilder.OutputTrivia(Microsoft.CodeAnalysis.SyntaxTrivia)">virtual</span> <span class="keyword" data-toggle="tooltip" title="void">void</span> <span data-toggle="tooltip" title="LiterateCS.BlockBuilder.OutputTrivia(Microsoft.CodeAnalysis.SyntaxTrivia)">OutputTrivia</span> <span class="punctuation">(</span><span class="typename" data-toggle="tooltip" title="Microsoft.CodeAnalysis.SyntaxTrivia">SyntaxTrivia</span> trivia<span class="punctuation">)</span>
		<span class="punctuation">{</span>
			<span data-toggle="tooltip" title="LiterateCS.BlockBuilder.AppendCode(string)"><a href="../LiterateCS/BlockBuilder.html#LiterateCS.BlockBuilder.AppendCode(string)">AppendCode</a></span> <span class="punctuation">(</span><span data-toggle="tooltip" title="Microsoft.CodeAnalysis.SyntaxTrivia">trivia</span><span class="punctuation" data-toggle="tooltip" title="Microsoft.CodeAnalysis.SyntaxTrivia.ToString()">.</span><span data-toggle="tooltip" title="Microsoft.CodeAnalysis.SyntaxTrivia.ToString()">ToString</span> <span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">)</span><span class="punctuation">;</span>
		<span class="punctuation">}</span>
</code></pre>
<h2 id="creating-macros">Creating Macros</h2>
<p>The visitor methods for regions handle creating new macros. When a region
is opened, we read its name and push a new macro with that name to the stack.
When the visitor methods are called, we have already added the new block which
starts the macro, so we can take its reference from the <code>_newBlock</code> field.</p>
<pre class="csharp"><code class="csharp">		<span class="keyword" id="LiterateCS.BlockBuilder.VisitRegionDirectiveTrivia(Microsoft.CodeAnalysis.CSharp.Syntax.RegionDirectiveTriviaSyntax)" data-toggle="tooltip" title="LiterateCS.BlockBuilder.VisitRegionDirectiveTrivia(Microsoft.CodeAnalysis.CSharp.Syntax.RegionDirectiveTriviaSyntax)">public</span> <span class="keyword" data-toggle="tooltip" title="LiterateCS.BlockBuilder.VisitRegionDirectiveTrivia(Microsoft.CodeAnalysis.CSharp.Syntax.RegionDirectiveTriviaSyntax)">override</span> <span class="keyword" data-toggle="tooltip" title="void">void</span> <span data-toggle="tooltip" title="LiterateCS.BlockBuilder.VisitRegionDirectiveTrivia(Microsoft.CodeAnalysis.CSharp.Syntax.RegionDirectiveTriviaSyntax)">VisitRegionDirectiveTrivia</span> <span class="punctuation">(</span>
			<span class="typename" data-toggle="tooltip" title="Microsoft.CodeAnalysis.CSharp.Syntax.RegionDirectiveTriviaSyntax">RegionDirectiveTriviaSyntax</span> node<span class="punctuation">)</span>
		<span class="punctuation">{</span>
			<span data-toggle="tooltip" title="System.Collections.Generic.Stack<LiterateCS.Macro>"><a href="../LiterateCS/BlockBuilder.html#LiterateCS.BlockBuilder._macros">_macros</a></span><span class="punctuation" data-toggle="tooltip" title="System.Collections.Generic.Stack<LiterateCS.Macro>.Push(LiterateCS.Macro)">.</span><span data-toggle="tooltip" title="System.Collections.Generic.Stack<LiterateCS.Macro>.Push(LiterateCS.Macro)">Push</span> <span class="punctuation">(</span><span class="typename" data-toggle="tooltip" title="LiterateCS.Macro"><a href="../LiterateCS/Macro.html#LiterateCS.Macro">Macro</a></span><span class="punctuation" data-toggle="tooltip" title="LiterateCS.Macro.Add(string, LiterateCS.BlockList, LiterateCS.BlockList, string)">.</span><span data-toggle="tooltip" title="LiterateCS.Macro.Add(string, LiterateCS.BlockList, LiterateCS.BlockList, string)"><a href="../LiterateCS/Macro.html#LiterateCS.Macro.Add(string, LiterateCS.BlockList, LiterateCS.BlockList, string)">Add</a></span> <span class="punctuation">(</span>
				<span data-toggle="tooltip" title="Microsoft.CodeAnalysis.CSharp.Syntax.RegionDirectiveTriviaSyntax">node</span><span class="punctuation" data-toggle="tooltip" title="Microsoft.CodeAnalysis.SyntaxToken">.</span><span data-toggle="tooltip" title="Microsoft.CodeAnalysis.SyntaxToken">EndOfDirectiveToken</span><span class="punctuation" data-toggle="tooltip" title="Microsoft.CodeAnalysis.SyntaxTriviaList">.</span><span data-toggle="tooltip" title="Microsoft.CodeAnalysis.SyntaxTriviaList">LeadingTrivia</span><span class="punctuation" data-toggle="tooltip" title="Microsoft.CodeAnalysis.SyntaxTriviaList.First()">.</span><span data-toggle="tooltip" title="Microsoft.CodeAnalysis.SyntaxTriviaList.First()">First</span> <span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation" data-toggle="tooltip" title="Microsoft.CodeAnalysis.SyntaxTrivia.ToString()">.</span><span data-toggle="tooltip" title="Microsoft.CodeAnalysis.SyntaxTrivia.ToString()">ToString</span> <span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">,</span>
				<span data-toggle="tooltip" title="LiterateCS.BlockList"><a href="../LiterateCS/BlockBuilder.html#LiterateCS.BlockBuilder._newBlock">_newBlock</a></span><span class="punctuation">,</span> <span class="keyword">null</span><span class="punctuation">,</span> <span data-toggle="tooltip" title="string"><a href="../LiterateCS/BlockBuilder.html#LiterateCS.BlockBuilder._currentFile">_currentFile</a></span><span class="punctuation">)</span><span class="punctuation">)</span><span class="punctuation">;</span>
		<span class="punctuation">}</span>
</code></pre>
<p>When a region is closed, we close the macro as well by popping it off the stack.
We also record the first block which does not belong to the macro (the end marker).</p>
<pre class="csharp"><code class="csharp">		<span class="keyword" id="LiterateCS.BlockBuilder.VisitEndRegionDirectiveTrivia(Microsoft.CodeAnalysis.CSharp.Syntax.EndRegionDirectiveTriviaSyntax)" data-toggle="tooltip" title="LiterateCS.BlockBuilder.VisitEndRegionDirectiveTrivia(Microsoft.CodeAnalysis.CSharp.Syntax.EndRegionDirectiveTriviaSyntax)">public</span> <span class="keyword" data-toggle="tooltip" title="LiterateCS.BlockBuilder.VisitEndRegionDirectiveTrivia(Microsoft.CodeAnalysis.CSharp.Syntax.EndRegionDirectiveTriviaSyntax)">override</span> <span class="keyword" data-toggle="tooltip" title="void">void</span> <span data-toggle="tooltip" title="LiterateCS.BlockBuilder.VisitEndRegionDirectiveTrivia(Microsoft.CodeAnalysis.CSharp.Syntax.EndRegionDirectiveTriviaSyntax)">VisitEndRegionDirectiveTrivia</span> <span class="punctuation">(</span>
			<span class="typename" data-toggle="tooltip" title="Microsoft.CodeAnalysis.CSharp.Syntax.EndRegionDirectiveTriviaSyntax">EndRegionDirectiveTriviaSyntax</span> node<span class="punctuation">)</span>
		<span class="punctuation">{</span>
			<span data-toggle="tooltip" title="System.Collections.Generic.Stack<LiterateCS.Macro>"><a href="../LiterateCS/BlockBuilder.html#LiterateCS.BlockBuilder._macros">_macros</a></span><span class="punctuation" data-toggle="tooltip" title="System.Collections.Generic.Stack<LiterateCS.Macro>.Pop()">.</span><span data-toggle="tooltip" title="System.Collections.Generic.Stack<LiterateCS.Macro>.Pop()">Pop</span> <span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation" data-toggle="tooltip" title="LiterateCS.BlockList">.</span><span data-toggle="tooltip" title="LiterateCS.BlockList"><a href="../LiterateCS/Macro.html#LiterateCS.Macro.End">End</a></span> <span class="punctuation" data-toggle="tooltip" title="LiterateCS.BlockList">=</span> <span data-toggle="tooltip" title="LiterateCS.BlockList"><a href="../LiterateCS/BlockBuilder.html#LiterateCS.BlockBuilder._newBlock">_newBlock</a></span><span class="punctuation">;</span>
		<span class="punctuation">}</span>
	<span class="punctuation">}</span>
<span class="punctuation">}</span>
</code></pre>

				</div>
				<ul class="pager">
	<li class="previous"><a href="../LiterateCS/Macro.html">Previous: Macros</a></li>
	<li class="next"><a href="../LiterateCS/HtmlBlockBuilder.html">Next: HTML Block Builder</a></li>
</ul>
			</div>
        </div>
    </div>
    
    <footer class="panel-footer text-center">
        <div align="center">Copyright © 2018 Tommi Johtela</div>
		<div align="right">
			<small>
				Documentation created with <a href="https://johtela.github.io/LiterateCS/">LiterateCS</a>.
			</small>
		</div>
    </footer>


    
    <script src="../bootstrap/js/jquery.min.js"></script>
    <script src="../bootstrap/js/bootstrap.min.js"></script>
    <script src="../sidebar/sidebar.js"></script>
    <script src="../syntax-highlight/syntax.js"></script>
    <script type="text/x-mathjax-config">
        MathJax.Hub.Config({
        extensions: ["jsMath2jax.js"]
        });
    </script>
    <script src='https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-AMS_HTML'></script>
	<script src="../mermaid/mermaid.min.js"></script>
	<script>mermaid.initialize({startOnLoad:true});</script>

</body>
</html>